#pragma once
#include <iostream>

template <typename T>
struct BaseTemplate {
void TemplMethod1() {
  step1();
  step2();
  step3();
  step4();
}

// 4 steps to run the TemplMethod1()
virtual void step1() = 0;
virtual void step2() = 0;
virtual void step3() = 0;
virtual void step4() = 0;

};

template <typename T>
struct TmplRunner : public BaseTemplate<T> {
  TmplRunner(T data) : m_data{data} {

  }


  void step1() override {
    std::cout << "Step1 impl " << std::endl;
  }

  void step2() override {
    std::cout << "Step2 impl " << std::endl;
  }

  void step3() override {
    std::cout << "Step3 impl " << std::endl;
  }
  
  void step4() override {
    std::cout << "Step4 impl " << std::endl;

    std::cout << "All step done, Now quit TmplMehtod1()" << std::endl;
  }

  private:
    T m_data;
};

// TODO: you can add more Son class that like using TemplMethod1 for 4 steps to finish a work
